package com.gzx.fin.tech.core.interceptor;

import com.gzx.plugin.fin.tech.cache.TenantCacheManager;
import com.gzx.plugin.fin.tech.entity.GzxFinTechTenant;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import vip.xiaonuo.common.util.CommonIpAddressUtil;
import vip.xiaonuo.common.util.CommonSignatureUtils;

import java.io.IOException;
import java.util.Arrays;

/**
 * @author zjt
 * @description
 * @date 2025/4/2 18:09
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class AuthInterceptor implements HandlerInterceptor {

	private final TenantCacheManager tenantCacheManager;

	@Override
	public boolean preHandle(HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler)
			throws Exception {
		// 1. 获取请求头
		String apiKey = request.getHeader("apiKey");
		String apiSecret = request.getHeader("apiSecret");
		String timestamp = request.getHeader("timestamp");
		String nonce = request.getHeader("nonce");
		String signature = request.getHeader("signature");
		String clientIp = CommonIpAddressUtil.getIp(request);
		// System.out.println("apiKey: " + apiKey + ", timestamp: " + timestamp + ",
		// signature: " + signature + ", clientIp: " + clientIp);
		// 2. 基础校验
		if (StringUtils.isAnyBlank(apiKey, apiSecret, timestamp, nonce, signature)) {
			sendError(response, 400, "请求头必填参数缺失");
			return false;
		}

		// 3. 检查时间戳有效期（5分钟）
		if (!isValidTimestamp(Long.parseLong(timestamp))) {
			sendError(response, 408, "时间戳过期");
			return false;
		}

		// 4. 查询租户信息
		GzxFinTechTenant tenant = tenantCacheManager.getTenantByApiKey(apiKey);
		if (tenant == null || !apiSecret.equals(tenant.getApiSecret())) {
			log.info("apiKey:{},apiSecret:{}--->{}", apiKey, apiSecret, tenant.getApiSecret());
			sendError(response, 401, "账号或密码错误");
			return false;
		} 

		// 5. IP白名单校验
		if (!isIpAllowed(clientIp, tenant.getAllowedIp())) {
			log.error("当前登录访问IP：{}", clientIp);
			sendError(response, 403, "非法IP");
			return false;
		}

		// 6. 验证签名
		if (!CommonSignatureUtils.verifyMd5Signature(request)) {
			sendError(response, 403, "签名错误");
			return false;
		}

		tenantCacheManager.setCurrentTenant(tenant);
		return true;
	}

	private boolean isValidTimestamp(long timestamp) {
		long current = System.currentTimeMillis();
		long timeDiff = current - timestamp; // 当前时间 - 请求时间戳
		return Math.abs(timeDiff) <= 300000; // 5分钟
	}

	private boolean isIpAllowed(String clientIp, String allowedIp) {
		if (StringUtils.isBlank(allowedIp)) {
			return false;
		}
		return Arrays.asList(allowedIp.split(",")).contains(clientIp);
	}

	private void sendError(HttpServletResponse response, int code, String msg) throws IOException {
		response.setContentType("application/json;charset=UTF-8");
		response.setStatus(code);
		response.getWriter().write("{\"code\":%d, \"msg\":\"%s\"}".formatted(code, msg));
	}

	public static void main(String[] args) {
		long aa = System.currentTimeMillis();
		System.out.println(aa);
		System.out.println(CommonSignatureUtils.generateMd5Signature("123456", "gzx", "zjtnb", String.valueOf(aa)));
	}
}
